﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace DesignPatternPractice.Creational.Prototype
{
    [Serializable]
    public class Product : ICloneable
    {
        private static Product prototypeProduct = new Product()
        {
            IntProperty = 10,
            StringProperty = "Hello",
            ListProperty = new List<int>()
            {
                1,
                2
            }
        };

        public object Clone()
        {
            /////////////////////////////////////////////////
            //浅表复制
            //return MemberwiseClone();
            /////////////////////////////////////////////////

            /////////////////////////////////////////////////
            //序列化
            //需要添加Serializable特性
            //缺点：如果包含自定义类型，需要自己写序列化函数
            string memory;
            using (MemoryStream stream = new MemoryStream())
            {
                new BinaryFormatter().Serialize(stream, this);

                memory = Convert.ToBase64String(stream.ToArray());
            }

            byte[] targetArray = Convert.FromBase64String(memory);

            object cloneProduct = null;

            using (MemoryStream stream = new MemoryStream(targetArray))
            {
                cloneProduct = new BinaryFormatter().Deserialize(stream);
            }

            return cloneProduct;
            /////////////////////////////////////////////////
        }

        public int IntProperty { get; set; }
        public string StringProperty { get; set; }
        public List<int> ListProperty { get; set; }

        public static Product CreateFromPrototype()
        {
            return (Product)prototypeProduct.Clone();
        }

        public void Show()
        {
            Console.WriteLine("++++++++++ Product ++++++++++");
            Console.WriteLine($"Int : {IntProperty}");
            Console.WriteLine($"String: {StringProperty}");

            Console.WriteLine("-- List --");
            foreach (var item in ListProperty)
            {
                Console.WriteLine(item);
            }

            Console.WriteLine("-- End --");

            Console.WriteLine("++++++++++ End ++++++++++");
        }
    }
}
